using System.Collections.Generic;
using OracleInternal.Common;
using OracleInternal.ConnectionPool;

namespace OracleInternal.MTS
{
	internal class MTSFreeTxnBranches
	{
		private object m_lock = new object();

		internal SyncDictionary<string, TxnBranchesByDBInst> m_freeBranchesByUserAuth = new SyncDictionary<string, TxnBranchesByDBInst>();

		internal int Count
		{
			get
			{
				int num = 0;
				List<string> keys = m_freeBranchesByUserAuth.GetKeys();
				TxnBranchesByDBInst txnBranchesByDBInst = null;
				for (int i = 0; i < keys.Count; i++)
				{
					txnBranchesByDBInst = m_freeBranchesByUserAuth[keys[i]];
					if (txnBranchesByDBInst != null)
					{
						num += txnBranchesByDBInst.BranchCount;
					}
				}
				return num;
			}
		}

		internal void ClearBranches()
		{
			List<string> keys = m_freeBranchesByUserAuth.GetKeys();
			TxnBranchesByDBInst txnBranchesByDBInst = null;
			for (int i = 0; i < keys.Count; i++)
			{
				m_freeBranchesByUserAuth[keys[i]]?.ClearBranches();
			}
			m_freeBranchesByUserAuth.Clear();
		}

		internal void EnqueueBranch(MTSTxnBranch txnBranch)
		{
			ConnectionString connCreds = txnBranch.m_connCreds;
			string dbInstance = txnBranch.m_dbInstance;
			TxnBranchesByDBInst txnBranchesByDBInst = null;
			if ((txnBranchesByDBInst = m_freeBranchesByUserAuth[connCreds.UserAuthenticationString]) == null)
			{
				lock (m_lock)
				{
					if ((txnBranchesByDBInst = m_freeBranchesByUserAuth[connCreds.UserAuthenticationString]) == null)
					{
						txnBranchesByDBInst = new TxnBranchesByDBInst();
						m_freeBranchesByUserAuth[connCreds.UserAuthenticationString] = txnBranchesByDBInst;
					}
				}
			}
			txnBranchesByDBInst.EnqueueBranch(dbInstance, txnBranch);
		}

		internal bool DequeueBranch(ConnectionString cs, string dbInstance, out MTSTxnBranch txnBranch)
		{
			TxnBranchesByDBInst txnBranchesByDBInst = null;
			txnBranch = null;
			if ((txnBranchesByDBInst = m_freeBranchesByUserAuth[cs.UserAuthenticationString]) == null)
			{
				return false;
			}
			return txnBranchesByDBInst.DequeueBranch(dbInstance, out txnBranch);
		}
	}
}
